package com.qfedu;

import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.github.pagehelper.PageInterceptor;
import com.qfedu.common.util.WoUtil;

// http://www.jb51.net/article/110772.htm
@SpringBootApplication
// @EntityScan(basePackages = "com.qfedu.psys.po")
@EnableTransactionManagement
@EnableCaching
// @ConditionalOnClass(value = {EndpointAutoConfiguration.class})
public class App {
	private final static Logger LOG = LogManager.getLogger(App.class);

	@Autowired
	private DataSource dataSource;

	// 集成mybatis配置：提供SqlSeesion
	@Bean(name = "sqlSessionFactory")
	public SqlSessionFactory sqlSessionFactoryBean() {
		try {
			SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
			sessionFactoryBean.setDataSource(dataSource);
			sessionFactoryBean.setVfs(SpringBootVFS.class);
			// 手写配置
			// 配置类型别名
			sessionFactoryBean.setTypeAliasesPackage("com.qfedu.psys.po");

			// 配置mapper的扫描，找到所有的mapper.xml映射文件
			Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml");
			sessionFactoryBean.setMapperLocations(resources);
			// 加载全局的配置文件
			// sessionFactoryBean
			// .setConfigLocation(new
			// DefaultResourceLoader().getResource("classpath:mybatis/mybatis-config.xml"));
			// 设置分页插件
			Properties p = new Properties();
			p.setProperty("helperDialect", "mysql");
			p.setProperty("offsetAsPageNum", "true");
			p.setProperty("rowBoundsWithCount", "true");
			p.setProperty("reasonable", "true");
			Interceptor it = new PageInterceptor();
			it.setProperties(p);
			sessionFactoryBean.setPlugins(new Interceptor[] { it });
			return sessionFactoryBean.getObject();
		} catch (IOException e) {
			LOG.warn("mybatis resolver mapper*.xml is error", e);
			return null;
		} catch (Exception e) {
			LOG.warn("mybatis sqlSessionFactoryBean create error");
			return null;
		}
	}

	// springboot集成activiti：https://blog.csdn.net/qq_33698579/article/details/80362864
	@Bean
	public SpringProcessEngineConfiguration processEngineConfiguration(PlatformTransactionManager transactionManager,
			DataSource dataSource) throws IOException {
		SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
		configuration.setTransactionManager(transactionManager);
		configuration.setDataSource(dataSource);
		configuration.setDatabaseSchemaUpdate("true");
		// configuration.setApplicationContext(WoUtil.getContext());
		// Map beans = new HashMap();
		// beans.put("teacherApplyServiceImpl", configuration.getApplicationContext().getBean("teacherApplyServiceImpl"));
		// configuration.setBeans(beans);
		// LOG.info(WoUtil.getContext());
		// 自动部署已有的流程文件
		Resource[] resources = new PathMatchingResourcePatternResolver()
				.getResources(ResourceLoader.CLASSPATH_URL_PREFIX + "processes/*.bpmn");
		configuration.setDeploymentResources(resources);
		configuration.setDbIdentityUsed(false);
		return configuration;
	}

	@Bean
	public ProcessEngine processEngine(SpringProcessEngineConfiguration processEngineConfiguration) throws IOException {
		LOG.info("processEngineConfiguration.getApplicationContext():" + processEngineConfiguration.getApplicationContext());
		return processEngineConfiguration.buildProcessEngine();
	}

	@Bean
	public RepositoryService repositoryService(ProcessEngine processEngine) {
		return processEngine.getRepositoryService();
	}

	@Bean
	public RuntimeService runtimeService(ProcessEngine processEngine) {
		return processEngine.getRuntimeService();
	}

	@Bean
	public TaskService taskService(ProcessEngine processEngine) {
		return processEngine.getTaskService();
	}

	@Bean
	public FormService formService(ProcessEngine processEngine) {
		return processEngine.getFormService();
	}

	@Bean
	public HistoryService historyService(ProcessEngine processEngine) {
		return processEngine.getHistoryService();
	}

	@Bean
	public ManagementService managementService(ProcessEngine processEngine) {
		return processEngine.getManagementService();
	}

	@Bean
	public IdentityService identityService(ProcessEngine processEngine) {
		return processEngine.getIdentityService();
	}

	public static void main(String[] args) {
		ApplicationContext context = SpringApplication.run(App.class, args);
		WoUtil.setContext(context);
	}
}
